#include "httprequest.h"

void httpRequest::run()
{
    // for (int i = 0; i < 5; ++i)
    // {
    //     position = "";
    //     if(GetPosition())
    //     {
    //         int start = position.indexOf('{');
    //         int end = position.indexOf('}');

    //         if(start != 0 && end != 0)
    //         {
    //             QString sub = position.mid(start + 1, end - start - 1);
    //             sub.replace("\"", "");
    //             sub.replace("city", "");
    //             sub.replace("province", "");
    //             sub.replace(":", "");
    //             emit httpSend(sub);
    //             return;
    //         }
    //         else
    //         {
    //             sleep(1);
    //         }
    //     }
    //     else
    //     {
    //         sleep(1);
    //     }
    // }
    // httpSend("fail to resolve");
    // closesocket(sock);
    // WSACleanup();

    QString result = queryIpLocation(this->request);

    //qDebug() << "查询结果:" << result;

    httpSend(result);
    return;
}

httpRequest::httpRequest()
{
    this->sock = INVALID_SOCKET;
    this->request = QUERY_IP;
    this->position = "";
    this->ip_addr = nullptr;
    this->buffer_size = 1024;
    memset(result, 0, 30);
}

bool httpRequest::GetIp(QString name)
{
    WSADATA wsa;
    if(WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
    {
        return false;
    }
    this->ip_addr = (char *)name.toStdString().c_str();

    if(inet_addr(ip_addr) == INADDR_NONE)
    {
        hostent *host = gethostbyname(ip_addr);
        if(host)
        {
            ip_addr = inet_ntoa(*(in_addr*)host->h_addr);
        }
        else
        {
            ip_addr = nullptr;
            return false;

        }
    }
    memcpy(result, ip_addr, strlen(ip_addr));
    return true;
}

bool httpRequest::ConnectHttpServer()
{
    sock = socket(AF_INET, SOCK_STREAM, 0);
    if(sock == INVALID_SOCKET)
    {
        return false;
    }
    else
    {
        SOCKADDR_IN in;
        in.sin_family = AF_INET;
        in.sin_port = htons(80);
        in.sin_addr.s_addr = inet_addr(result);

        if(::connect(sock, (SOCKADDR *)&in, sizeof(SOCKADDR)) !=0)
        {
            return false;
        }
    }
    return true;
}

bool httpRequest::GetPosition()
{
    char package[500] = "GET /ipquery"
                        "?ip=";
    strcat(package, request.toStdString().c_str());
    strcat(package, " HTTP/1.1\r\nHost:"
           "ip.ws.126.net\r\n"
           "Connection: Keep-alive\r\n"
           "Cache-Control: max-age=0\r\n"
           "Upgrade-Insecure-Requests: 1\r\n"
           "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\r\n"
           "Accept-Language:zh-CN,zh;q=0.8\r\n\r\n");

    char recv_buffer[1024];
    ZeroMemory(recv_buffer, 1024);

    if(!GetIp("ip.ws.126.net"))
    {
        return false;
    }

    if(!ConnectHttpServer())
    {
        return false;
    }

    if(!SetSockInfo())
    {
        return false;
    }

    if(send(sock, package, strlen(package), 0) <= 0)
    {
        return false;
    }
    if(recv(sock, recv_buffer, sizeof(recv_buffer), 0) <= 0)
    {
        return false;
    }

    QTextCodec *codec = QTextCodec::codecForName("GBK");
    position = codec->toUnicode(recv_buffer);
    qDebug()<<position;
}

bool httpRequest::SetSockInfo()
{
    if(setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char *)&buffer_size, sizeof(int)) == SOCKET_ERROR)
    {
        return false;
    }
    if(setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (char *)&buffer_size, sizeof(int)) == SOCKET_ERROR)
    {
        return false;
    }
    return true;
}

void httpRequest::SetIpAddr(QString ip_addr)
{
    this->request = ip_addr;
}

QString httpRequest::queryIpLocation(const QString& ipAddress) {
    QNetworkAccessManager manager;
    QEventLoop loop;
    QString urlStr = QString("https://www.ipshudi.com/%1.htm").arg(ipAddress);
    QNetworkRequest request(urlStr);
    request.setHeader(QNetworkRequest::UserAgentHeader,
                      "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36");

    QNetworkReply* reply = manager.get(request);
    QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
    loop.exec();

    QString location;
    if (reply->error() == QNetworkReply::NoError) {
        QString content = QString::fromUtf8(reply->readAll());

        //qDebug()<<content;

        // 使用 DotMatchesEverythingOption 替代 DotAllOption
        QRegularExpression re("<td class=\"th\">ASN归属地</td><td><span>(.*?)</span></td>",
                              QRegularExpression::DotMatchesEverythingOption);
        QRegularExpressionMatch match = re.match(content);

        if (match.hasMatch()) {
            location = match.captured(1);
        } else {
            QRegularExpression re2("<td class=\"th\">归属地</td>\n<td>\n<span>(.*?)</span>",
                                   //<td class=\"th\">归属地</td>\n<td>\n<span>中国 上海市  浦东新区</span>
                                   QRegularExpression::DotMatchesEverythingOption);
            match = re2.match(content);
            if (match.hasMatch()) {
                location = match.captured(1);
            } else {
                location = "未找到匹配的地理位置信息";
            }
        }
    } else {
        location = QString("网络错误: %1").arg(reply->errorString());
    }

    reply->deleteLater();
    return location;
}
